package com.controller;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.conf.AppInterceptor;
import com.conf.Constant;
import com.google.code.kaptcha.Producer;
import com.service.UserService;
import com.util.*;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.hibernate.validator.constraints.Length;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.awt.image.BufferedImage;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

@Validated
@RestController
@RequestMapping("/user")
@Api(tags = {"账号"})
public class UserController {

    private final static Logger log = LoggerFactory.getLogger(UserController.class);

    @Autowired
    private Producer captchaProducer;

    @Autowired
    UserService userService;

    //图片验证码
    ConcurrentHashMap<Long,String> imgCaptcha = new ConcurrentHashMap<>();

    //短信验证码
    ConcurrentHashMap<Long,String> smsCaptcha = new ConcurrentHashMap<>();

    //每10分钟清理图片验证码
    @Scheduled(cron = "0 0/10 * * * ? ")
    public void removeImgCaptcha(){
        long time = System.currentTimeMillis()-10*60000;
        Enumeration<Long> keys = imgCaptcha.keys();
        while (keys.hasMoreElements()) {
            long oldTime = keys.nextElement();
            if(oldTime < time){
                imgCaptcha.remove(oldTime);
            }
        }
    }

    @ApiOperation("获取图片验证码")
    @GetMapping("/getImgCaptcha")
    public AjaxResult getImgCaptcha(@ApiParam(value = "上一个图片验证码标识")
                                    @RequestParam(name = "uuid",required = false) @Length(max = 32) String uuid){
        if(!UtilCheck.isEmpty(uuid)){
            log.info("删除验证码:{}",uuid);
            imgCaptcha.remove(uuid);
        }
        String captchaText = captchaProducer.createText();
        log.info("图形验证码:{}",captchaText);
        long time = System.currentTimeMillis();
        BufferedImage bufferedImage = captchaProducer.createImage(captchaText);
        Map<String,String> mapResult = new HashMap<>();
        mapResult.put("uuid",""+time);
        mapResult.put("img",UtilImg.getImgBase64(bufferedImage,"jpg"));
        //
        imgCaptcha.put(time,captchaText);
        return AjaxResult.getOk(mapResult);
    }

    @ApiOperation(value = "密码登录")
    @PostMapping("/pwdLogin")
    public AjaxResult pwdLogin(
            @ApiParam(value = "uuid", required = true)
            @RequestParam(name = "uuid",required = false) @Empty(max = 32) String uuid,
            @ApiParam(value = "验证码", required = true)
            @RequestParam(name = "code",required = false) @Empty(max = 10) String code,
            @ApiParam(value = "手机号",type = "String", required = true)
            @Empty(max = 11)
            @RequestParam(name = "phone",required = false) String phone,
            @ApiParam(value = "密码", required = true)
            @RequestParam(name = "pwd",required = false) @Empty String pwd){
        String vcode = imgCaptcha.get(Long.valueOf(uuid));
        if(UtilCheck.isEmpty(vcode)){
            return AjaxResult.getFail("验证码过期,请刷新");
        }
        if(!vcode.equals(code)){
            return AjaxResult.getFail("验证码错误");
        }
        //删除匹配的图片验证码
        imgCaptcha.remove(Long.valueOf(uuid));
        //
        pwd = UtilMD5.getMD5(pwd);
        return userService.pwdLogin(phone,pwd);
    }

    //每20分钟清理验证码
    @Scheduled(cron = "0 0/20 * * * ? ")
    public void removeSmsCaptcha(){
        long time = System.currentTimeMillis()-20*60000;
        Enumeration<Long> keys = smsCaptcha.keys();
        while (keys.hasMoreElements()) {
            long oldTime = keys.nextElement();
            if(oldTime < time){
                smsCaptcha.remove(oldTime);
            }
        }
    }

    @ApiOperation("发送短信验证码")
    @GetMapping("/getSmsCaptcha")
    public AjaxResult getSmsCaptcha(@PathVariable("uuid") @RequestParam(name = "uuid",required = false) String uuid,
                                 @ApiParam(value = "手机号",type = "String", required = true)
                                 @Empty(max = 11)
                                 @RequestParam(name = "phone",required = false) String phone){
        if(!UtilCheck.isEmpty(uuid)){
            log.info("删除验证码:{}",uuid);
            smsCaptcha.remove(uuid);
        }
        String captchaText = captchaProducer.createText();
        log.info("短信验证码:{}",captchaText);
        long time = System.currentTimeMillis();
        Map<String,String> mapResult = new HashMap<>();
        mapResult.put("uuid",""+time);
        mapResult.put("phone",phone);
        //
        smsCaptcha.put(time,captchaText);
        return AjaxResult.getOk(mapResult);
    }

    @ApiOperation(value = "短信登录")
    @PostMapping("/smsLogin")
    public AjaxResult smsLogin(
            @ApiParam(value = "uuid", required = true)
            @RequestParam(name = "uuid",required = false) @Empty(max = 32) String uuid,
            @ApiParam(value = "验证码", required = true)
            @RequestParam(name = "code",required = false) @Empty(max = 10) String code,
            @ApiParam(value = "手机号",type = "String", required = true)
            @Phone
            @RequestParam(name = "phone",required = false) String phone){
        String vcode = smsCaptcha.get(Long.valueOf(uuid));
        if(UtilCheck.isEmpty(vcode)){
            return AjaxResult.getFail("验证码过期,请刷新");
        }
        if(!vcode.equals(code)){
            return AjaxResult.getFail("验证码错误");
        }
        //删除匹配的短信验证码
        smsCaptcha.remove(Long.valueOf(uuid));
        return userService.smsLogin(phone);
    }

    @ApiOperation(value = "注册")
    @PostMapping("/save")
    public AjaxResult save(
           @ApiParam(value = "账号", required = true)
           @RequestParam(name = "username",required = false)
           @Empty(max = 16) String username,
           @ApiParam(value = "昵称")
           @RequestParam(name = "nickname",required = false) String nickname,
           @ApiParam(value = "手机号")
           @RequestParam(name = "phone",required = false) String phone,
           @ApiParam(value = "姓名")
           @RequestParam(name = "name",required = false) String name,
           @ApiParam(value = "密码")
           @RequestParam(name = "pwd",required = false) String pwd,
           @ApiParam(value = "角色id ['角色id']")
           @RequestParam(name = "role_id",required = false) String role_id){
        if(UtilCheck.isEmpty(name) && UtilCheck.isEmpty(nickname)){
            name = username;
            nickname = username;
        }
        if(UtilCheck.isPhone(username) && UtilCheck.isEmpty(phone)){
            phone = username;
        }
        if(UtilCheck.isEmpty(name) && UtilCheck.isNotEmpty(nickname)){
            name = nickname;
        }
        if(UtilCheck.isEmpty(nickname) && UtilCheck.isNotEmpty(name)){
            nickname = name;
        }
        if(UtilCheck.isEmpty(pwd)){
            pwd = "123456";
        }
        pwd = UtilMD5.getMD5(pwd);
        List<String> listRoleId = null;
        if(!UtilCheck.isEmpty(role_id)){
            listRoleId = JSONArray.parseArray(role_id,String.class);
        }
        return userService.save(username,name,nickname,phone, pwd,listRoleId);
    }

    @ApiOperation(value = "修改")
    @PutMapping("/update")
    public AjaxResult update(
            @ApiParam(value = "账号id", required = true)
            @RequestParam(name = "user_id",required = false)
            @Empty(max = 11) String user_id,
            @ApiParam(value = "账号", required = true)
            @RequestParam(name = "username",required = false)
            @Empty(max = 16) String username,
            @ApiParam(value = "昵称")
            @RequestParam(name = "nickname",required = false) String nickname,
            @ApiParam(value = "手机号")
            @RequestParam(name = "phone",required = false) String phone,
            @ApiParam(value = "姓名")
            @RequestParam(name = "name",required = false) String name,
            @ApiParam(value = "密码")
            @RequestParam(name = "pwd",required = false) String pwd,
            @ApiParam(value = "角色id ['角色id']")
            @RequestParam(name = "role_id",required = false) String role_id){
        if(UtilCheck.isEmpty(name) && UtilCheck.isEmpty(nickname)){
            name = username;
            nickname = username;
        }
        if(UtilCheck.isPhone(username) && UtilCheck.isEmpty(phone)){
            phone = username;
        }
        if(UtilCheck.isEmpty(name) && UtilCheck.isNotEmpty(nickname)){
            name = nickname;
        }
        if(UtilCheck.isEmpty(nickname) && UtilCheck.isNotEmpty(name)){
            nickname = name;
        }
        List<String> listRoleId = null;
        if(!UtilCheck.isEmpty(role_id)){
            listRoleId = JSON.parseArray(role_id,String.class);
        }
        return userService.update(user_id,username,name,phone,nickname,pwd,listRoleId);
    }

    @ApiOperation(value = "删除")
    @DeleteMapping("/del")
    public AjaxResult del(@ApiParam(value = "账号id", required = true)
                         @RequestParam(name="user_id",required = false)
                         @Empty(max = 11) String user_id){
        return userService.del(user_id);
    }

    @ApiOperation(value = "分页列表")
    @PostMapping("/list")
    public AjaxResult list(@ApiParam(value = "昵称") @Length(max = 16) String nickname,
                           @ApiParam(value = "手机号") @Length(max = 11) String phone,
                           @ApiParam(value = "当前页", required = true)
                           @RequestParam(name = "pageNum")
                           @Num(message = "当前页不可用") String pageNum,
                           @ApiParam(value = "每页条数", required = true)
                           @RequestParam(name = "pageSize")
                           @Num(message = "每页条数不可用") String pageSize){
        return userService.list(nickname,phone,pageNum,pageSize);
    }

    @ApiOperation(value = "配置角色")
    @PutMapping("/configRoles")
    public AjaxResult configRoles(
            @ApiParam(value = "账号id", required = true)
            @RequestParam(name = "user_id")
            @Length(max = 11) String user_id,
            @ApiParam(value = "角色id ['角色id']")
            @RequestParam(name = "role_id",required = false) String role_id){
        List<String> list = JSONArray.parseArray(role_id,String.class);
        return userService.configRoles(user_id,list);
    }

    @ApiOperation(value = "我的菜单")
    @GetMapping("/getMenuList")
    public AjaxResult getMenuList(@ApiParam(hidden = true)
                                  @RequestAttribute(name = Constant.UserId) String user_id){
        return userService.getMenuList(user_id);
    }

    @ApiOperation(value = "退出登录")
    @GetMapping("/exitLogin")
    public AjaxResult exitLogin(@ApiParam(hidden = true)
                                @RequestHeader(name = Constant.Authorization) String token){
        AppInterceptor.tokenUser.remove(token);
        return AjaxResult.getOk();
    }

    @ApiOperation(value = "登录信息")
    @GetMapping("/getLogin")
    public AjaxResult getLogin(@ApiParam(hidden = true)
                               @RequestAttribute(name = Constant.Nickname) String nickname,
                               @ApiParam(hidden = true)
                               @RequestAttribute(name = Constant.Phone) String phone){
        Map<String,Object> user = new HashMap<>();
        user.put("nickname",nickname);
        user.put("phone",phone);
        return AjaxResult.getOk(user);
    }

    @ApiOperation(value = "下拉列表")
    @GetMapping("/select")
    public AjaxResult select(@ApiParam(value = "手机号")
                             @RequestParam(name = "phone",required = false) String phone){
        return userService.select(phone);
    }

}
